package com.sixeco.carservice.modular.device.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * ReadWriteLock 读写锁的使用
 * @author daify
 * @date 2019-06-18 11:45
 **/
public class ReadWriteLockTest {

    private ReadWriteLock lock = new ReentrantReadWriteLock(false);
    
    /**
     * 非公平锁，
     * 可以不传递参数，默认值
     */
    private ReadWriteLock nonfairSync = new ReentrantReadWriteLock(false);

    /**
     * 公平锁
     */
    private ReadWriteLock fairSync = new ReentrantReadWriteLock(true);

    /**
     * 锁的简单用法 ——写
     */
    public Thread getReadThread () {
        return new Thread(new Runnable() {
            @Override
            public void run() {
                Lock readLock = lock.readLock();
                readLock.lock();
                try {
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName() + "得到了读锁");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    readLock.unlock();
                    System.out.println(Thread.currentThread().getName() + "释放了读锁.");
                }
            }
        });
    }

    public Thread getWriteThread () {
        return new Thread(new Runnable() {
            @Override
            public void run() {
                Lock writeLock = lock.writeLock();
                writeLock.lock();
                try {
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName() + "得到了写锁");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    writeLock.unlock();
                    System.out.println(Thread.currentThread().getName() + "释放了写锁.");
                }
            }
        });
    }

    /**
     * 写不可并发
     * 读可以并发
     */
    public void tryReadAndWriteTest() {
        Thread t3 = getWriteThread();
        Thread t4 = getWriteThread();
        t3.setName("线程C");
        t4.setName("线程D");
        t3.start();
        
        Thread t = getReadThread();
        Thread t2 = getReadThread();
        Thread t5 = getReadThread();
        Thread t6 = getReadThread();
        t.setName("线程A");
        t2.setName("线程B");
        t5.setName("线程E");
        t6.setName("线程F");
        t.start();
        t2.start();
        t4.start();
        t5.start();
        t6.start();
    }


    public static void main(String[] args) {
        ReadWriteLockTest test = new ReadWriteLockTest();
        test.tryReadAndWriteTest();
    }
    
}
